//静态方法和非静态方法的区别？以及使用场景？
/*
* 1.静态方法用static修饰，在类被定义的时候就已经被装载和分配
*   非静态方法，在类定义时没有占内存，当实例化的成对象时，对象调用该方法才会占用内存
* 2.静态的属性和方法，不用经过实例化，就可以访问类中的静态属性和方法
*   static声明的属性和方法是和类有关系的，不是和类的某个特性的实例有关系
* 3.静态的属性和方法只能访问静态的属性和方法，不能访问非静态的属性和方法，因为静态属性和方法被创建的时候，可能还没有任何这个类的实例可以被调用
*   静态的属性和方法要访问非静态的属性和方法，要先实例化当前类的对象，然后通过对象调用非静态的属性和方法
* 4. static的属性，在内存中只有一分，被所有的实例共用，不论有多少个实例，静态属性和方法只有一个；
* */


/**
 * 设备或配置系统参数
 * @param string $name 参数名称
 * @param bool $value 默认是false为获取值，否则为更新
 * @return string|bool
 */
function sysconf($name, $value = false) {
    static $config = [];
    if ($value !== false) {
        $config = [];
        $data = ['name' => $name, 'value' => $value];
        return DataService::save('SystemConfig', $data, 'name');
    }
    if (empty($config)) {
        foreach (Db::name('SystemConfig')->select() as $vo) {
            $config[$vo['name']] = $vo['value'];
        }
    }
    return isset($config[$name]) ? $config[$name] : '';
}


class DataService {

    /**
     * 删除指定序号
     * @param string $sequence
     * @param string $type
     * @return bool
     */
    public static function deleteSequence($sequence, $type = 'SYSTEM') {
        $data = ['sequence' => $sequence, 'type' => strtoupper($type)];
        return Db::name('SystemSequence')->where($data)->delete();
    }

    /**
     * 生成唯一序号 (失败返回 NULL )
     * @param int $length 序号长度
     * @param string $type 序号顾类型
     * @return string
     */
    public static function createSequence($length = 10, $type = 'SYSTEM') {
        $times = 0;
        while ($times++ < 10) {
            $sequence = '';
            $i = 0;
            while ($i++ < $length) {
                $sequence .= ($i <= 1 ? rand(1, 9) : rand(0, 9));
            }
            $data = ['sequence' => $sequence, 'type' => strtoupper($type)];
            if (Db::name('SystemSequence')->where($data)->count() < 1 && Db::name('SystemSequence')->insert($data)) {
                return $sequence;
            }
        }
        return null;
    }

    /**
     * 数据增量保存
     * @param \think\db\Query|string $dbQuery 数据查询对象
     * @param array $data 需要保存或更新的数据
     * @param string $upkey 条件主键限制
     * @param array $where 其它的where条件
     * @return bool
     */
    public static function save($dbQuery, $data, $upkey = 'id', $where = []) {
        $db = is_string($dbQuery) ? Db::name($dbQuery) : $dbQuery;
        $fields = $db->getTableFields(['table' => $db->getTable()]);
        $_data = [];
        foreach ($data as $k => $v) {
            in_array($k, $fields) && ($_data[$k] = $v);
        }
        if (self::_apply_save_where($db, $data, $upkey, $where)->count() > 0) {
            return self::_apply_save_where($db, $data, $upkey, $where)->update($_data) !== FALSE;
        }
        return self::_apply_save_where($db, $data, $upkey, $where)->insert($_data) !== FALSE;
    }

    /**
     * 应用 where 条件
     * @param \think\db\Query|string $db 数据查询对象
     * @param array $data 需要保存或更新的数据
     * @param string $upkey 条件主键限制
     * @param array $where 其它的where条件
     * @return \think\db\Query
     */
    protected static function _apply_save_where(&$db, $data, $upkey, $where) {
        foreach (is_string($upkey) ? explode(',', $upkey) : $upkey as $v) {
            if (is_string($v) && array_key_exists($v, $data)) {
                $db->where($v, $data[$v]);
            } elseif (is_string($v)) {
                $db->where("{$v} IS NULL");
            }
        }
        return $db->where($where);
    }

    /**
     * 更新数据表内容
     * @param \think\db\Query|string $dbQuery 数据查询对象
     * @param array $where 额外查询条件
     * @return bool|null
     */
    public static function update(&$dbQuery, $where = []) {
        $db = is_string($dbQuery) ? Db::name($dbQuery) : $dbQuery;
        $ids = explode(',', input("post.id", ''));
        $field = input('post.field', '');
        $value = input('post.value', '');
        $pk = $db->getPk(['table' => $db->getTable()]);
        $db->where(empty($pk) ? 'id' : $pk, 'in', $ids);
        !empty($where) && $db->where($where);
        // 删除模式
        if ($field === 'delete') {
            $fields = $db->getTableFields(['table' => $db->getTable()]);
            if (in_array('is_deleted', $fields)) {
                return false !== $db->update(['is_deleted' => 1]);
            }
            return false !== $db->delete();
        }
        // 更新模式
        return false !== $db->update([$field => $value]);
    }

}
